//
//  UINavigationController+HHUIKit.m
//  ZHUIKit
//
//  Created by admin on 2018/7/20.
//

#import "UINavigationController+HHUIKit.h"
#import <BCFoundation/BCSwizzle.h>
#import <BCFoundation/BCFoundationUtils.h>
#import "UINavigationBar+BCHelper.h"
#import "UIViewController+HHPage.h"
#import "UINavigationItem+BCHelper.h"
#import "BCComConfigKit/BCComConfigKit.h"
#import <BCFoundation/UIImage+BCHelper.h>

@interface UINavigationController ()<UINavigationControllerDelegate, UIGestureRecognizerDelegate>

@end

@implementation UINavigationController (HHUIKit)

#pragma mark - system
+ (void)load
{
    BCSwizzleInstanceMethod([UINavigationController class], BCHookSelector(@"initWithRootViewController:"), BCSWReturnType(UINavigationController *), BCSWArguments(UIViewController * rootViewController), BCSWReplacement({
        [selfObj hh_initWithRootViewController:rootViewController];
        UINavigationController *navcPage = BCSWCallOriginal(rootViewController);
        return navcPage;
    }));

    BCSwizzleInstanceMethod([UINavigationController class], BCHookSelector(@"viewDidLoad"), BCSWReturnType(void), BCSWArguments(), BCSWReplacement({
        BCSWCallOriginal();
        [selfObj hh_navcViewDidLoad];
    }));

    BCSwizzleInstanceMethod([UINavigationController class], @selector(pushViewController:animated:), BCSWReturnType(void), BCSWArguments(UIViewController * viewController, BOOL animated), BCSWReplacement({
        UINavigationController *hh_selfObj = (UINavigationController *)selfObj;
        if (hh_selfObj.viewControllers.count > 0) {
            viewController.hidesBottomBarWhenPushed = YES;
        }
        BCSWCallOriginal(viewController, animated);
        if (!hh_selfObj.bc_enableSwizzle) {
            return;
        }
        [selfObj hh_pushViewController:viewController animated:animated];
    }));

    BCSwizzleInstanceMethod([UINavigationController class], @selector(popViewControllerAnimated:), BCSWReturnType(UIViewController *), BCSWArguments(BOOL animated), BCSWReplacement({
        [selfObj hh_popViewControllerAnimated:animated];
        UIViewController *zhPage = BCSWCallOriginal(animated);
        return zhPage;
    }));

    // modalPresentationStyle
    BCSwizzleInstanceMethod([UINavigationController class], BCHookSelector(@"modalPresentationStyle"), BCSWReturnType(UIModalPresentationStyle), BCSWArguments(), BCSWReplacement({
        if ([selfObj bc_enableSwizzle] && [selfObj hh_childModalPresentationStyle]) {
            //自定义
            return [selfObj bc_modalPresentationStyle];
        } else {
            //如果vc不支持swizzle
            return BCSWCallOriginal();
        }
    }));
}

+ (instancetype)bc_initWithRootPage:(NSString *)clsRootPage
{
    Class clspage = NSClassFromString(clsRootPage);
    if (!clspage) {
        return nil;
    }
    UIViewController *vcPage = [[clspage alloc] init];
    UINavigationController *navPageInstance = [[[self class] alloc] initWithRootViewController:vcPage];
    return navPageInstance;
}

- (void)hh_initWithRootViewController:(UIViewController *)rootViewController
{
    self.bc_enableSwizzle = rootViewController.bc_enableSwizzle;
}

- (void)hh_navcViewDidLoad
{
    if (!self.bc_enableSwizzle) {
        return;
    }
    self.navigationController.delegate = self;
    __weak __typeof(self) weakSelf = self;
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.delegate = weakSelf;
        self.delegate = weakSelf;
    }
    [self bc_restore];
}

#pragma mark - 恢复导航栏
- (void)bc_restore {
    //配置导航栏
    [self bc_restoreTitle];
    if (BCComConfig.config.navShadowImg) {
        [self.navigationBar setShadowImage:BCComConfig.config.navShadowImg];
    }
    if (BCComConfig.config.navBgColor) {
        [self.navigationBar bc_setBackgroundColor:BCComConfig.config.navBgColor];
    }
}

- (void)bc_restoreTitle {
    [self.navigationBar setTitleTextAttributes:@{ NSForegroundColorAttributeName: BCComConfig.config.navTitleColor,  NSFontAttributeName: BCComConfig.config.bcBoldFont(18) }];//默认字体
    [self.navigationBar setTintColor:BCComConfig.config.navTitleColor];
}

#pragma mark - push ViewController

- (void)bc_pushPage:(NSString *)scheme animated:(BOOL)animated {
    Class clspage = NSClassFromString(scheme);
    if (!clspage) {
        return;
    }
    UIViewController *vcPage = [[clspage alloc] init];
    [self pushViewController:vcPage animated:animated];
}

- (void)hh_pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (!self.bc_enableSwizzle) {
        return;
    }
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.enabled = !viewController.bc_disablePopGesture;
    }
    if (viewController.navigationItem.leftBarButtonItem == nil) {
        // ZHPhotoBrowser 统一处理导航栏背景透明或者黑色
        if ([viewController isKindOfClass:NSClassFromString(@"ZHPhotoBrowser")]) {
            [self.navigationBar bc_setBackgroundColor:[UIColor clearColor]];
        }
        //判断最顶部的vc 是不是当前push的vc。如果不是，可能已经push了，但是 viewControllers 列表没有更新
        if ([self.viewControllers count] <= 1) {
            UIViewController *topVC = self.viewControllers.lastObject;
            if (topVC == viewController) {
                return;
            }
        }
        if (!viewController.hh_hideBackItem) {
            //需要back bar
            BCWeakObj(self);
            UIImage *itemImg = viewController.hh_navBackImage ?: BCComConfig.config.navBackImg;
            [viewController.navigationItem bc_setLeftItemImg:itemImg text:nil action:^(UIButton *sender) {
                BCStrongObj(self);
                [self bc_backItemAction];
            }];
        } else {
            //不需要back bar
            [viewController.navigationItem bc_setLeftItem:nil];
            viewController.navigationItem.hidesBackButton = YES;
        }
    }
}

#pragma mark - pop ViewController
- (void)hh_popViewControllerAnimated:(BOOL)animated
{
    if (!self.bc_enableSwizzle) {
        return;
    }
    // ZHPhotoBrowser 统一处理返回是重置导航栏
    UIViewController *viewController = [self.childViewControllers lastObject];
    if ([viewController isKindOfClass:NSClassFromString(@"ZHPhotoBrowser")]) {
        [self bc_restore];
    }
}

- (void)bc_popViewControllWithNames:(NSArray *)clsNames animated:(BOOL)animated {
    NSArray *reversedArray = [[self.viewControllers reverseObjectEnumerator] allObjects];
    //0 第一个为当前显示的 忽略
    for (NSInteger i = 1; i < reversedArray.count; i++) {
        UIViewController *VC = reversedArray[i];
        for (NSString *clsName in clsNames) {
            if ([VC isKindOfClass:NSClassFromString(clsName)]) {
                [self popToViewController:VC animated:animated];
                return;
            }
        }
    }
    [self popViewControllerAnimated:animated];
}

#pragma mark - 移除viewcontroller
- (void)bc_removeViewController:(UIViewController *)viewController animated:(BOOL)animated {
    if (self.viewControllers.count > 0) {
        NSMutableArray *mViewControllers = [[NSMutableArray alloc] initWithArray:self.viewControllers];
        [viewController dismissViewControllerAnimated:false completion:nil];
        [mViewControllers removeObject:viewController];
        [self setViewControllers:mViewControllers animated:animated];
    }
}
-(void)bc_removeViewControllers:(NSArray<UIViewController *> *)controllers withAnimated:(BOOL)animated {
    if (self.viewControllers.count == 0) { return ; }
    NSMutableArray *mViewControllers = [[NSMutableArray alloc] initWithArray:self.viewControllers];
    [mViewControllers removeObjectsInArray:controllers];
    [self setViewControllers:mViewControllers animated:animated];
}
- (void)bc_removeViewControllers:(NSArray<NSString *> *)clsNames animated:(BOOL)animated {
    if (self.viewControllers.count == 0) {
        return;
    }
    NSMutableArray *mViewControllers = [[NSMutableArray alloc] initWithArray:self.viewControllers];
    for (UIViewController *viewController in mViewControllers.reverseObjectEnumerator) {
        for (NSString *vcName in clsNames) {
            if ([viewController isKindOfClass:NSClassFromString(vcName)]) {
                [viewController dismissViewControllerAnimated:false completion:nil];
                [mViewControllers removeObject:viewController];
                break;
            }
        }
    }
    [self setViewControllers:mViewControllers animated:animated];
}
-(void)bc_removeViewControllersWithClasses:(NSArray<Class > *)classes withAnimated:(BOOL)animated {
    if (self.viewControllers.count == 0) {
        return;
    }
    NSMutableArray *mViewControllers = [[NSMutableArray alloc] initWithArray:self.viewControllers];
    for (UIViewController *viewController in mViewControllers.reverseObjectEnumerator) {
        for (Class vcClass in classes) {
            if ([viewController isKindOfClass:vcClass]) {
                [mViewControllers removeObject:viewController];
                [viewController dismissViewControllerAnimated:false completion:nil];
                break;
            }
        }
    }
    [self setViewControllers:mViewControllers animated:animated];
}

#pragma mark - event
- (void)bc_backItemAction
{
    if (self.viewControllers.count == 1) {
        [self dismissViewControllerAnimated:YES completion:nil];
    } else {
        [self popViewControllerAnimated:YES];
    }
}

#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animate
{
    if (!self.bc_enableSwizzle) {
        return;
    }
    if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        // disable interactivePopGestureRecognizer in the rootViewController of navigationController
        // and disable ZHPhotoBrowser popGesture
        if ([[navigationController.viewControllers firstObject] isEqual:viewController] || viewController.bc_disablePopGesture || [viewController isKindOfClass:NSClassFromString(@"ZHPhotoBrowser")]) {
            navigationController.interactivePopGestureRecognizer.enabled = NO;
        } else {
        // enable interactivePopGestureRecognizer
            navigationController.interactivePopGestureRecognizer.enabled = ![viewController bc_disablePopGesture];
        }
    }
}

#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if (!self.bc_enableSwizzle) {
        return YES;
    }
    if (gestureRecognizer == self.interactivePopGestureRecognizer) {
        if (self.viewControllers.count < 2 || self.visibleViewController == [self.viewControllers objectAtIndex:0]) {
            return NO;
        }
    }
    return YES;
}

#pragma mark - childViewControllerForStatusBarStyle
- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

#pragma mark - Rotate
// 是否支持自动转屏
- (BOOL)shouldAutorotate {
    return [self.visibleViewController shouldAutorotate];
}

// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return [self.visibleViewController supportedInterfaceOrientations];
}

// 默认的屏幕方向（当前ViewController必须是通过模态出来的UIViewController（模态带导航的无效）方式展现出来的，才会调用这个方法）
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return [self.visibleViewController preferredInterfaceOrientationForPresentation];
}

///MARK: -modalPresentationStyle
- (UIModalPresentationStyle)bc_modalPresentationStyle {
    return [self.visibleViewController modalPresentationStyle];
}

///MARK: -@property
- (BOOL)hh_childModalPresentationStyle
{
    return [objc_getAssociatedObject(self, @selector(hh_childModalPresentationStyle)) boolValue];
}

- (void)setHh_childModalPresentationStyle:(BOOL)hh_childModalPresentationStyle
{
    objc_setAssociatedObject(self, @selector(hh_childModalPresentationStyle), @(hh_childModalPresentationStyle), OBJC_ASSOCIATION_ASSIGN);
}

@end
